//
//  File.swift
//  LocationTrackerAdmin
//
//  Created by mac on 2025/4/10.
//

import Foundation
import Fluent
import FluentKit
import AppStoreServerLibrary
import Vapor

final class SubscriptionRecordModel: Model, Content {
    static let schema = "apple_subscription_record"
    // Transaction identifiers
//    @ID(key: "original_transaction_id")
//    var id: String?
    @ID(custom: "original_transaction_id")
    var id: String?
    
    @Field(key: "transaction_id")
    var transactionId: String?
    
    @Field(key: "web_order_line_item_id")
    var webOrderLineItemId: String?
    
    // App information
    @Field(key: "bundle_id")
    var bundleId: String?
    
    @Field(key: "product_id")
    var productId: String?
    
    @Field(key: "subscription_group_identifier")
    var subscriptionGroupIdentifier: String?
    
    // Dates
    @Field(key: "purchase_date")
    var purchaseDate: Date?
    
    @Field(key: "original_purchase_date")
    var originalPurchaseDate: Date?
    
    @Field(key: "expires_date")
    var expiresDate: Date?
    
    @Field(key: "signed_date")
    var signedDate: Date?
    
    @Field(key: "revocation_date")
    var revocationDate: Date?
    
    // Transaction details
    @Field(key: "quantity")
    var quantity: Int32?
    
    @Field(key: "type")
    var type: String?
    
    @Field(key: "app_account_token")
    var appAccountToken: UUID?
    
    @Field(key: "in_app_ownership_type")
    var inAppOwnershipType: String?
    
    @Field(key: "revocation_reason")
    var revocationReason: Int32?
    
    @Field(key: "is_upgraded")
    var isUpgraded: Bool?
    
    // Offer details
    @Field(key: "offer_type")
    var offerType: Int32?
    
    @Field(key: "offer_identifier")
    var offerIdentifier: String?
    
    @Field(key: "offer_discount_type")
    var offerDiscountType: String?
    
    @Field(key: "offer_period")
    var offerPeriod: String?
    
    // Store details
    @Field(key: "environment")
    var environment: String?
    
    @Field(key: "storefront")
    var storefront: String?
    
    @Field(key: "storefront_id")
    var storefrontId: String?
    
    @Field(key: "transaction_reason")
    var transactionReason: String?
    
    // Pricing
    @Field(key: "currency")
    var currency: String?
    
    @Field(key: "price")
    var price: Int64?
    
    // App transaction
    @Field(key: "app_transaction_id")
    var appTransactionId: String?
    
    init() {}
    
    init(from payload: JWSTransactionDecodedPayload) {
        self.id = payload.originalTransactionId
        self.transactionId = payload.transactionId
        self.webOrderLineItemId = payload.webOrderLineItemId
        self.bundleId = payload.bundleId
        self.productId = payload.productId
        self.subscriptionGroupIdentifier = payload.subscriptionGroupIdentifier
        self.purchaseDate = payload.purchaseDate
        self.originalPurchaseDate = payload.originalPurchaseDate
        self.expiresDate = payload.expiresDate
        self.quantity = payload.quantity
        self.type = payload.rawType
        self.appAccountToken = payload.appAccountToken
        self.inAppOwnershipType = payload.rawInAppOwnershipType
        self.signedDate = payload.signedDate
        self.revocationReason = payload.rawRevocationReason
        self.revocationDate = payload.revocationDate
        self.isUpgraded = payload.isUpgraded
        self.offerType = payload.rawOfferType
        self.offerIdentifier = payload.offerIdentifier
        self.environment = payload.rawEnvironment
        self.storefront = payload.storefront
        self.storefrontId = payload.storefrontId
        self.transactionReason = payload.rawTransactionReason
        self.currency = payload.currency
        self.price = payload.price
        self.offerDiscountType = payload.rawOfferDiscountType
        self.appTransactionId = payload.appTransactionId
        self.offerPeriod = payload.offerPeriod
    }
    
    func toDecodedPayload() -> JWSTransactionDecodedPayload {
        JWSTransactionDecodedPayload(
            originalTransactionId: id,
            transactionId: transactionId,
            webOrderLineItemId: webOrderLineItemId,
            bundleId: bundleId,
            productId: productId,
            subscriptionGroupIdentifier: subscriptionGroupIdentifier,
            purchaseDate: purchaseDate,
            originalPurchaseDate: originalPurchaseDate,
            expiresDate: expiresDate,
            quantity: quantity,
            rawType: type,
            appAccountToken: appAccountToken,
            rawInAppOwnershipType: inAppOwnershipType,
            signedDate: signedDate,
            rawRevocationReason: revocationReason,
            revocationDate: revocationDate,
            isUpgraded: isUpgraded,
            rawOfferType: offerType,
            offerIdentifier: offerIdentifier,
            rawEnvironment: environment,
            storefront: storefront,
            storefrontId: storefrontId,
            rawTransactionReason: transactionReason,
            currency: currency,
            price: price,
            rawOfferDiscountType: offerDiscountType,
            appTransactionId: appTransactionId,
            offerPeriod: offerPeriod
        )
    }
}

struct SubscriptionRecordModelMigration: AsyncMigration {
    func prepare(on database: Database) async throws {
        try await database.schema(SubscriptionRecordModel.schema)
            // Transaction identifiers
            .field("original_transaction_id", .string, .identifier(auto: false))
            .field("transaction_id", .string)
            .field("web_order_line_item_id", .string)
            .field("bundle_id", .string)
            .field("product_id", .string)
            .field("subscription_group_identifier", .string)
            .field("purchase_date", .datetime)
            .field("original_purchase_date", .datetime)
            .field("expires_date", .datetime)
            .field("signed_date", .datetime)
            .field("revocation_date", .datetime)
            .field("quantity", .int32)
            .field("type", .string)
            .field("app_account_token", .uuid)
            .field("in_app_ownership_type", .string)
            .field("revocation_reason", .int32)
            .field("is_upgraded", .bool)
            .field("offer_type", .int32)
            .field("offer_identifier", .string)
            .field("offer_discount_type", .string)
            .field("offer_period", .string)
            .field("environment", .string)
            .field("storefront", .string)
            .field("storefront_id", .string)
            .field("transaction_reason", .string)
            .field("currency", .string)
            .field("price", .int64)
            .field("app_transaction_id", .string)
            .create()
    }
    
    func revert(on database: Database) async throws {
        try await database.schema(SubscriptionRecordModel.schema).delete()
    }
}
